feat: Add compute aggregation kernels (Sum/Min/Max/Mean)#379
feat: Add compute aggregation kernels (Sum/Min/Max/Mean)#379luisquintanilla wants to merge 5 commits into
Conversation
## What's Changed Adds a new Apache.Arrow.Compute project with SIMD-accelerated Sum/Min/Max/Mean aggregation kernels for PrimitiveArray<T>, backed by System.Numerics.Tensors (TensorPrimitives). When NullCount == 0 the kernels dispatch to TensorPrimitives for one vectorized pass over the contiguous Values span; with nulls they fall back to a validity-aware scalar loop. The project is AOT-compatible with scalar fallbacks for older target frameworks, and pulls in System.Numerics.Tensors via Directory.Packages.props. Includes an xUnit test project (Apache.Arrow.Compute.Tests, 11 tests) covering int32, int64, float, and double, with and without nulls, and the empty-array case. The new projects are added to Apache.Arrow.sln and the test to Apache.Arrow.Tests.slnf. This implements the aggregation-kernel portion of apache#375; elementwise kernels and the Tensor<T> wrapper described there remain as follow-ups. Part of apache#375.
|
This overlaps a bit with #257, at least in spirit. FYI @mobiusklein. |
|
I ran out of bandwidth. The scope of my PR was too large to work through in the time I had available. If @luisquintanilla wants to adapt any of that material, please feel free to. Otherwise, I won't be able to cycle back to it in the next month at least. |
|
Thanks folks. I'll take a look and see how to reconcile both PRs where possible. To @CurtHagenlocher point, seems like they're both aiming to add operations to |
## What's Changed Makes the Apache.Arrow.Compute aggregation kernels build across the same target frameworks as Apache.Arrow (netstandard2.0;net8.0;net462): - On net8.0+ the kernels stay generic over INumber<T> and dispatch to System.Numerics.Tensors (TensorPrimitives) on the null-free fast path. - On netstandard2.0/net462 (where generic math and TensorPrimitives are unavailable) they fall back to per-type scalar kernels for Int32Array/Int64Array/FloatArray/DoubleArray. - Documents the LINQ-style null semantics (nulls are skipped; Sum of an empty or all-null array is zero; Min/Max/Mean throw InvalidOperationException when there are no non-null elements). Adds an Apache.Arrow.Compute.Benchmarks project (BenchmarkDotNet) comparing the SIMD fast path against a naive managed loop over the same buffer; the SIMD Sum is several times faster at large sizes with zero allocation. Wires the benchmark project into Apache.Arrow.sln. Part of apache#375.
|
Pushed an update that gets this PR closer to mergeable (keeping it as a draft for now):
This is the first slice of #375; a roadmap for the follow-on slices (elementwise kernels, On the project home / naming. These are compute kernels in the sense of C++ |
|
@CurtHagenlocher this one's ready for review. Thanks! |
adamreeve
left a comment
There was a problem hiding this comment.
Thanks @luisquintanilla, I've left a few minor comments.
To fix the CI tests, you'll need to update dev/release/verify_rc.ps1 and dev/release/verify_rc.sh to make the new test project reference the nuget packages. See here and here.
The documentation build is also failing, it's not immediately obvious to me how to fix that.
|
Thanks for the review @adamreeve I believe I've addressed all the issues and feedback. |
I think some of these LINQ semantics would be surprising to most data folks. Is there a difficulty in typing
I don't have a super strong preference about this, other than to insist that if we have an additional assembly then there must be clear guidelines about how to decide between the two where functionality goes. I don't see a particularly clear line between "compute operations" and "non-compute operations" but I also haven't put very much thought into it. |
FWIW, I checked how PyArrow's compute module behaves and it returns None in these scenarios. Making these return a |
What's Changed
Adds a new
Apache.Arrow.Computeproject with SIMD-accelerated Sum/Min/Max/Mean aggregation kernels forPrimitiveArray<T>, backed bySystem.Numerics.Tensors(TensorPrimitives). WhenNullCount == 0the kernels dispatch toTensorPrimitivesfor one vectorized pass over the contiguousValuesspan; with nulls they fall back to a validity-aware scalar loop. The project is AOT-compatible with scalar fallbacks for older target frameworks, and pulls inSystem.Numerics.TensorsviaDirectory.Packages.props.Includes an xUnit test project (
Apache.Arrow.Compute.Tests, 11 tests) covering int32, int64, float, and double, with and without nulls, and the empty-array case. The new projects are added toApache.Arrow.slnand the test toApache.Arrow.Tests.slnf.This implements the aggregation-kernel portion of #375; the elementwise kernels and
Tensor<T>wrapper described there remain as follow-ups.Part of #375.